/*
* Copyright (c) 2008, Vladimir Gumenuk
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the copyright holder nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// GNXEdit.cpp : implementation file
//

#include "stdafx.h"
#include "RealGNX4Lib.h"
#include "GNXEdit.h"


// CGNXEdit
IMPLEMENT_DYNAMIC(CGNXEdit, CEdit)

CGNXEdit::CGNXEdit()
{
    m_iMin = 0;
    m_iMax = 0;
    m_fMin = 0.0f;
    m_fMax = 0.0f;
    m_iSpinMin = -1;
    m_iSpinMax = -1;
    m_vt   = VT_EMPTY;
}

CGNXEdit::~CGNXEdit()
{
}

BEGIN_MESSAGE_MAP(CGNXEdit, CEdit)
    ON_CONTROL_REFLECT(EN_CHANGE, OnEditCtrlChanged)
END_MESSAGE_MAP()

void CGNXEdit::DataExchange( CDataExchange *pDX, int iIDEdit, int iIDSpin )
{
    DDX_Control( pDX, iIDEdit, *this );
    DDX_Control( pDX, iIDSpin, m_Spin );
}

// CGNXEdit message handlers
void CGNXEdit::OnEditCtrlChanged()
{
    char szBuf[32] = {0};
    GetWindowText( szBuf, 32 );

    switch( m_vt )
    {
    case VT_I4:
        {
            int i = atoi( szBuf );
            if( i < m_iMin )
            {
                i = m_iMin;
                SetValue( i );
            } 
            else 
            if( i > m_iMax )
            {
                i = m_iMax;
                SetValue( i );
            }   
        }
        break;
    case VT_R4:
        {
            float f = (float)atof( szBuf );
            if( f < m_fMin )
            {
                f = m_fMin;
                SetFltValue( f );
            }
            else
            if( f > m_fMax )
            {
                f = m_fMax;
                SetFltValue( f );
            }    
        }
        break;
    default:
        ASSERT( FALSE );
        break;
    }
}

BOOL CGNXEdit::GetVisible()
{
    return IsWindowVisible();
}

void CGNXEdit::SetVisible( BOOL bVis )
{
    int nCmd = ( bVis ) ? SW_SHOW : SW_HIDE;
    ShowWindow( nCmd );
    m_Spin.ShowWindow( nCmd );
}

void CGNXEdit::Initialize( int iMin, int iMax )
{
    m_vt = VT_I4;
    m_iMin = iMin;
    m_iMax = iMax;
    m_Spin.Initialize( m_iMin, m_iMax, this );
}

void CGNXEdit::SetValue( int i )
{
    char szBuf[32];

    switch( m_vt )
    {
    case VT_I4:
        if( i < m_iMin )
            i = m_iMin;
        else if( i > m_iMax )
            i = m_iMax;
        sprintf_s( szBuf, "%d", i );
        break;

    case VT_R4:
        {
            int x = m_iMax / 2;
            float f = (float)( i - x ) / 2.0f;
            sprintf_s( szBuf, "%.01f", f );
        }
        break;
    default:
        ASSERT( FALSE );
        break;
    }

    SetWindowText( szBuf );
    if( m_Spin.GetPos32() != i )
        m_Spin.SetPos32( i );
}

int CGNXEdit::GetValue()
{
    ASSERT( m_vt == VT_I4 );
    char szBuf[32] = {0};
    GetWindowText( szBuf, 32 );
    int i = atoi( szBuf );
    if( i < m_iMin )
        i = m_iMin;
    if( i > m_iMax )
        i = m_iMax;

    return i;
}

// CGNXEdit message handlers
void CGNXEdit::Initialize( float fMin, float fMax, int iSpinMin, int iSpinMax )
{
    m_vt   = VT_R4;
    m_fMin = fMin;
    m_fMax = fMax;
    m_iMin = iSpinMin;
    m_iMax = iSpinMax;
    m_Spin.Initialize( iSpinMin, iSpinMax, this );
}

void CGNXEdit::SetFltValue( float f )
{
    ASSERT( m_vt == VT_R4 );
    char szBuf[32];

    if( f < m_fMin )
        f = m_fMin;
    else if( f > m_fMax )
        f = m_fMax;

    sprintf_s( szBuf, "%.01f", f );
    SetWindowText( szBuf );

    int x = (int)( f * 2.0f ) + ( m_iMax / 2 ); 
    m_Spin.SetPos32( x );
}

float CGNXEdit::GetFltValue()
{
    ASSERT( m_vt == VT_R4 );
    char szBuf[32] = { 0 };
    GetWindowText( szBuf, 32 );

    float f = (float)atof( szBuf );
    if( f < m_fMin )
        f = m_fMin;
    if( f > m_fMax )
        f = m_fMax;

    return f;
}

// CGNXSpin
IMPLEMENT_DYNAMIC(CGNXSpin, CSpinButtonCtrl)

CGNXSpin::CGNXSpin()
{
    m_iMin = 0;
    m_iMax = 0;
    m_pEdit = NULL;
}

CGNXSpin::~CGNXSpin()
{
}

BEGIN_MESSAGE_MAP(CGNXSpin, CSpinButtonCtrl)
    ON_NOTIFY_REFLECT_EX(UDN_DELTAPOS, OnDeltapos)
END_MESSAGE_MAP()

void CGNXSpin::Initialize( int iMin, int iMax, CGNXEdit *pEdit )
{
    ASSERT( pEdit );
    m_iMin = iMin;
    m_iMax = iMax;
    m_pEdit = pEdit;

    SetRange32( m_iMin, m_iMax );
    SetBase( 10 );
    UDACCEL udAccel[6] = { 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 10 };
    SetAccel( 5, &udAccel[0] );
}

void CGNXSpin::SetValue( int i )
{
    if( i < m_iMin )
        i = m_iMin;
    else if( i > m_iMax )
        i = m_iMax;
    SetPos32( i );
}

int CGNXSpin::GetValue()
{
    return GetPos32();
}

BOOL CGNXSpin::OnDeltapos( NMHDR* pNMHDR, LRESULT* pResult )
{
    NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
    if( m_pEdit )
        m_pEdit->SetValue( pNMUpDown->iPos );
    *pResult = 0;
    return TRUE;
}

//////////////////////////////////////////////////////////////////////////
//
IMPLEMENT_DYNAMIC(CGNXCheck, CButton)

BEGIN_MESSAGE_MAP(CGNXCheck, CButton)
    ON_CONTROL_REFLECT(BN_CLICKED, OnBtnClicked)
END_MESSAGE_MAP()

void CGNXCheck::OnBtnClicked()
{
    if( m_pData )
    {
        *m_pData = (WORD)GetCheck();
        //TRACE( "m_pData: %d\n", *m_pData );

        CFormView *pView = (CFormView *)GetParent();
        CDocument *pDoc = pView->GetDocument();
        pDoc->SetModifiedFlag();
    }
}